package com.emode.base;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.xwork.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Transactional;
@SuppressWarnings("unchecked")
public class BaseDaoImpl<T> extends BaseService<T> implements BaseDao<T> {
	private static Logger logger = Logger.getLogger(BaseDaoImpl.class);  
	protected Class<T> clazz;
	
	//参数化类型反射  
	public BaseDaoImpl(){
		ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
		this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
		logger.debug("clazz="+clazz.getName());
		System.out.println("clazz="+clazz.getName());
	}

	@Override
	@Transactional
	public void save(T entity) {
		ht.save(entity);
		logger.debug("FlushMode="+ht.getFlushMode());
		
	}


	@Override
	@Transactional
	public void update(T entity) {
		ht.update(entity);
	}

	@Override
	public T getById(Serializable Id) {
		if(Id == null){
			return null;
		}
		return (T) ht.get(clazz, Id);
	}


	public List<T> getByIds(Long[] ids) {
		if(ids == null || ids.length == 0){
			return Collections.EMPTY_LIST;
		}
		return Query(
				"FROM "+clazz.getSimpleName()+" where id in(:ids)");
	}

	@Override
	public List<T> findAll() {
		return Query(
				"FROM "+clazz.getSimpleName());
	}

	/* 批量删除操作
	 * @see com.emode.base.BaseDao#deleteByIds(java.io.Serializable[])
	 */
	@Override
	@Transactional
	public void deleteByIds(Serializable... ids) {
		if(ids!=null&&ids.length>0){
			for(Serializable id:ids){
				Object entity = ht.get(clazz, id);//找到当前的id
				if(entity==null){
					throw new RuntimeException("您要查找的ID不存在");
				}
				ht.delete(entity);
				System.out.println("FlushMode="+ht.getFlushMode());
				logger.info("FlushMode="+ht.getFlushMode());
			}
		}
	}

	/* 删除所有
	 * @see com.emode.base.BaseDao#deleteAllObjects(java.util.Collection)
	 */
	@Override
	@Transactional
	public void deleteAllObjects(Collection<T> entities) {
		ht.deleteAll(entities);
	}

	/*
	 *没有分页的查找
	 * @see com.emode.base.BaseDao#findObjectByConditionWithNoPage(java.lang.String, java.lang.Object[])
	 */
	@Override
	public List<T> findObjectByConditionWithNoPage(String whereHql,Object[] values) {
		return findObjectByConditionWithNoPage(whereHql,values,null);
	}

	/* (non-Javadoc)
	 * @see com.emode.base.BaseDao#findObjectByConditionWithPage(java.util.LinkedHashMap)
	 */
	@Override
	public List<T> findObjectByConditionWithPage(LinkedHashMap<String, String> oderby) {
		// TODO Auto-generated method stub
		return  findObjectByConditionWithNoPage(null,null,oderby);
	}

	/* (non-Javadoc)
	 * @see com.emode.base.BaseDao#findObjectByConditionWithPage(java.lang.String, java.lang.Object[], java.util.LinkedHashMap)
	 */
	@Override
	public List<T> findObjectByConditionWithPage(String whereHql,
			Object[] values, LinkedHashMap<String, String> orderby,Pager p) {
		Integer count  = getObjectCountsByid(whereHql, values);
		System.out.println("查询条数为"+count);
		p.init(count);
		String tmpHql = getTmpHql(whereHql, orderby);
		System.out.println("---->tmpHql:"+tmpHql);
		return PageQuery(tmpHql, p,values);
	}
	
	/*
	 * 得到处理的查询语句
	 */
	private String getTmpHql(String whereHql,
			LinkedHashMap<String, String> orderby) {
		String tmpHql = "select o from "+clazz.getSimpleName() +" o where 1 = 1";
		if(StringUtils.isNotBlank(whereHql)){
			tmpHql = tmpHql+whereHql;
		}
		//处理排序
		String orderbystr = buildOrdeyBy(orderby);
		tmpHql=tmpHql+orderbystr;
		return tmpHql;
	}

	/**
	 * 处理排序问题
	 * @param orderby
	 */
	public String buildOrdeyBy(LinkedHashMap<String, String> orderby) {
		StringBuffer buf = new StringBuffer("");
		if(orderby!=null&&!orderby.isEmpty()){
			buf.append(" order by ");
			for(Map.Entry<String, String> em:orderby.entrySet()){
				buf.append(em.getKey()+" "+em.getValue());
			}
			//去掉最后一个 “，”逗号
			buf.deleteCharAt(buf.length()-1);
			System.out.println("buf:"+buf.toString());
		}
		return buf.toString();
	}

	/* 通过Id得到条数，可以传条件
	 * @see com.emode.base.BaseDao#getObjectCountsByid(java.io.Serializable)
	 */
	@Override
	public int getObjectCountsByid(String whereHql,Object... values) {
		String hql = "select count(o) from "+clazz.getSimpleName()+" o where 1 = 1";
		//判断whereHql
		if(StringUtils.isNotBlank(whereHql)){
			hql=hql+whereHql;
		}
		int count = getCount(hql, values);
		return count;
	}

	/* 和分页查询的一点区别，没有传入page值
	 *  return list
	 */
	@Override
	public List<T> findObjectByConditionWithNoPage(String whereHql,
			Object[] values, LinkedHashMap<String, String> orderby) {
		String tmpHql = getTmpHql(whereHql, null);
		System.out.println("----->tmpHql:"+tmpHql);
		return ht.find(tmpHql, values);
	}

	@Override
	public List<T> findObjectByConditionWithNoPageCache(String whereHql,
			Object[] values, LinkedHashMap<String, String> orderby) {
		String tmpHql = getTmpHql(whereHql, orderby);
		final String fhql = tmpHql;
		return QueryByCache(fhql, values);
	}

	@Override
	public List<T> findObjectByConditionWithPageCache(String whereHql,
			Object[] values, LinkedHashMap<String, String> orderby, Pager p) {
		String tmpHql = getTmpHql(whereHql, orderby);
		final String fhql = tmpHql;
		return PageQueryByCache(fhql, p, values);
	}
	
}
